package com.siyoumi.service.wx;

import com.alibaba.fastjson.JSONObject;
import com.siyoumi.component.XRedis;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.config.SysConfig;
import com.siyoumi.entity.SysAccsuperConfig;
import com.siyoumi.entity.SysAccsuperConfigService;
import com.siyoumi.entity.WxUser;
import com.siyoumi.entity.WxUserService;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.feign.view_admin.SiyoumiFeign;
import com.siyoumi.mybatispuls.IWebService;
import com.siyoumi.service.entity.AesKi;
import com.siyoumi.service.vo.VoLogin;
import com.siyoumi.service.vo.VoWxAppQr;
import com.siyoumi.service.wx.api.ApiConfig;
import com.siyoumi.service.wx.api.WxApiApp;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

//接口
@Slf4j
@Service
public class WxApiServiceWxAppImpl
        implements WxApiService, IWebService {
    @Override
    @Transactional
    public XReturn login(VoLogin vo) {
        XHttpContext.setX(vo.getX());

        SysAccsuperConfig entityConfig = XHttpContext.getXConfig(true);
        if (entityConfig == null) {
            return EnumSys.ERR_VAL.getR();
        }
        if (XStr.isNullOrEmpty(entityConfig.getAconfig_app_id())) {
            return EnumSys.MISS_VAL.getR("miss app_id");
        }
        if (!entityConfig.wxOpen()) {
            if (XStr.isNullOrEmpty(entityConfig.getAconfig_app_secret())) {
                return EnumSys.MISS_VAL.getR("miss app_secret");
            }
        }

        WxApiApp miniProgram = WxApiApp.getIns(entityConfig);
        if (entityConfig.wxOpenClient()) {
            SysAccsuperConfig entityConfigParent = SysAccsuperConfigService.getBean().getXConfigWxOpenParent(entityConfig.getX());
            ApiConfig apiConfigParent = new ApiConfig();
            apiConfigParent.setAppId(entityConfigParent.getAconfig_app_id());
            apiConfigParent.setAccessToken(WxTokenService.getBean(entityConfigParent).getAccessToken());
            miniProgram.getConfig().setParent(apiConfigParent);
        }

        XReturn r = miniProgram.getUserInfo(vo.getCode());
        if (r.err()) {
            return r;
        }

        String openid = r.getData("openid");
        String unionid = r.getData("unionid", "");
        //String session_key = r.getData("session_key");

        //更新用户
        WxUserService appWxUser = WxUserService.getBean();
        WxUser entityWxUser = appWxUser.getByOpenid(openid, false);

        //为了不更新所有字段，需要new
        WxUser entityWxUserUpdate = new WxUser();
        if (entityWxUser == null) {
            entityWxUserUpdate.setWxuser_id(openid);
        }
        entityWxUserUpdate.setWxuser_openid(openid);
        entityWxUserUpdate.setWxuser_x_id(entityConfig.getKey());

        //unionid
        if (XStr.hasAnyText(unionid)) {
            entityWxUserUpdate.setWxuser_unionid(unionid);
        }
        try {
            entityWxUser = appWxUser.saveOrUpdatePassEqualField(entityWxUser, entityWxUserUpdate);
        } catch (Exception ex) {
            log.error(ex.getMessage());
            ex.printStackTrace();
            XValidator.err(EnumSys.SYS.getR(ex.getMessage()));
        }

        //前端返回参数
        return loginReturnDataWx(entityWxUser, entityConfig);
    }

    @Override
    public XReturn loginSetOpenid(String token) {
        if (XStr.isNullOrEmpty(token)) {
            return EnumSys.MISS_VAL.getR("miss token");
        }

        XRedis.getBean().setEx(token, getOpenid(), 300);
        return XReturn.getR(0);
    }

    @Override
    public XReturn getPhone(String code) {
        if (XStr.isNullOrEmpty(code)) {
            return EnumSys.MISS_VAL.getR("miss code");
        }

        SysAccsuperConfig entityConfig = XHttpContext.getXConfig(true);
        WxApiApp app = WxApiApp.getIns(entityConfig);
        XReturn r = app.getUserPhone(code);
        if (r.ok()) {
            JSONObject entity = r.getData("phone_info");
            String phone = entity.getString("phoneNumber");

            AesKi aesKi = AesKi.of(entityConfig.getAconfig_token());

            JSONObject phoneInfo = new JSONObject();
            phoneInfo.put("phoneNumber", phone);
            phoneInfo.put("phoneNumberEnc", aesKi.encTxt(phone));

            r.setData("phone_info", phoneInfo);
        }

        return r;
    }

    /**
     * 生成小程序码
     *
     * @param vo
     */
    public byte[] wxappQr(VoWxAppQr vo) {
        SysAccsuperConfig config;
        if ("x".equals(XHttpContext.get("x"))) {
            config = SiyoumiFeign.getBean().getConfigCenter();
        } else {
            config = SysAccsuperConfigService.getBean().getXConfig(XHttpContext.getX(), true);
        }

        WxApiApp miniProgram = WxApiApp.getIns(config);

        if (XStr.isNullOrEmpty(vo.getPath())) {
            vo.setPath("pages/login/login");
        }

        Map<String, Object> mapAppend = new HashMap<>();
        if (vo.getIs_hyaline() == 1) {
            mapAppend.put("is_hyaline", true);
        }

        if (SysConfig.getIns().isDev()) {
            log.debug("开发环境");
            vo.setEnv_version("develop");
        }
        mapAppend.put("check_path", false);
        if ("release".equals(vo.getEnv_version())) {
            log.debug("正式环境，路径不存在，会报错");
            mapAppend.put("check_path", true);
        }

        return miniProgram.getQrCodeUnlimited(vo.getScene(), vo.getPath(), mapAppend);
    }
}
